package org.fuys.coder.domain.audit.service.policy.audit.impl;

import com.alibaba.fastjson2.JSONObject;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.TextModerationRequest;
import com.aliyun.green20220302.models.TextModerationResponse;
import com.aliyun.green20220302.models.TextModerationResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import org.fuys.coder.common.config.AliYunOssConfig;
import org.fuys.coder.domain.config.service.impl.CoderAuditConfig;
import org.fuys.coder.domain.audit.model.req.AuditTask;
import org.fuys.coder.domain.audit.model.res.AuditResult;
import org.fuys.coder.domain.audit.model.vo.AuditResultTypeVO;
import org.fuys.coder.domain.audit.service.policy.audit.AuditStrategy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.domain.audit.service.policy.audit
 * @className: TextAuditStrategy
 * @author: WangJing
 * @description: 文本审核策略
 * @date: 2024/6/22 16:50
 * @version: 1.0
 */
@Service("textAuditStrategy")
public class TextAuditStrategy implements AuditStrategy {
    @Resource
    private CoderAuditConfig config;

    @Resource
    private AliYunOssConfig ossConfig;

    private Client client;

    @PostConstruct
    public void initClient(){
        Config config=new Config();
        config.setAccessKeyId(ossConfig.getAccessKeyId());
        config.setAccessKeySecret(ossConfig.getAccessKeySecret());
        config.setRegionId(ossConfig.getRegion());
        config.setEndpoint("green-cip.cn-beijing.aliyuncs.com");
        config.setReadTimeout(6000);
        config.setConnectTimeout(3000);
        try {
            client=new Client(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public AuditResult execute(AuditTask auditTask) {
        final String[] texts = auditTask.getTasks();
        //todo 暂不考虑文本超过20000字的情况
        if(texts.length>1) {
            List<AuditResult> list=new ArrayList<>();
            for (String text : texts) {
                final AuditResult auditResult = doAudit(text);
                list.add(auditResult);
            }
            return merge(list);
        }
        return doAudit(texts[0]);
    }

    private AuditResult merge(List<AuditResult> list){
        if(list.size()==1){
            return list.get(0);
        }
        AuditResult result=AuditResult.normal();
        for (AuditResult auditResult : list) {
            if(auditResult.getType()!=AuditResultTypeVO.PASS.getIndex()){
                return auditResult;
            }
        }
        return result;
    }
    private AuditResult doAudit(String text){
        RuntimeOptions runtimeOptions=new RuntimeOptions();
        runtimeOptions.readTimeout=10000;
        runtimeOptions.connectTimeout=10000;

        //构造检测参数
        JSONObject serviceParameters=new JSONObject();
        text=text.trim();
        if(text.length()==0){
            return AuditResult.normal();
        }
        serviceParameters.put("content",text);
        TextModerationRequest textModerationRequest=new TextModerationRequest();
        //文本检测的service模型代码
        textModerationRequest.setService(config.getTextService());
        textModerationRequest.setServiceParameters(serviceParameters.toJSONString());

        //调用客户端进行检测
        try{
            final TextModerationResponse response = client.textModerationWithOptions(textModerationRequest, runtimeOptions);
            if(ObjectUtils.isEmpty(response)){
                //todo 如果是空 说明审核失败 加入死信交换机
                return null;
            }else{
                if (200==response.getStatusCode()) {
                    final TextModerationResponseBody result = response.getBody();
                    final Integer code = result.getCode();
                    if(!ObjectUtils.isEmpty(code)&&code==200){
                        TextModerationResponseBody.TextModerationResponseBodyData data=result.getData();
                        final String labels = data.getLabels();
                        if (!labels.equals("")){
                            return AuditResult.abnormal(AuditResultTypeVO.BLOCK.getIndex(),
                                    labels);
                        }else{
                            return AuditResult.normal();
                        }
                    }
                }else{
                    //todo 如果是空 说明审核失败 加入死信交换机
                    return null;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
